/*
 * Funambol is a mobile platform developed by Funambol, Inc.
 * Copyright (C) 2008 Funambol, Inc.
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU Affero General Public License version 3 as published by
 * the Free Software Foundation with the addition of the following permission
 * added to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED
 * WORK IN WHICH THE COPYRIGHT IS OWNED BY FUNAMBOL, FUNAMBOL DISCLAIMS THE
 * WARRANTY OF NON INFRINGEMENT  OF THIRD PARTY RIGHTS.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program; if not, see http://www.gnu.org/licenses or write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02110-1301 USA.
 *
 * You can contact Funambol, Inc. headquarters at 643 Bair Island Road, Suite
 * 305, Redwood City, CA 94063, USA, or at email address info@funambol.com.
 *
 * The interactive user interfaces in modified source and object code versions
 * of this program must display Appropriate Legal Notices, as required under
 * Section 5 of the GNU Affero General Public License version 3.
 *
 * In accordance with Section 7(b) of the GNU Affero General Public License
 * version 3, these Appropriate Legal Notices must retain the display of the
 * "Powered by Funambol" logo. If the display of the logo is not reasonably
 * feasible for technical reasons, the Appropriate Legal Notices must display
 * the words "Powered by Funambol".
 */

#import <Foundation/Foundation.h>

#import "UIController.h"
#import "FunambolAPI.h"
#ifndef FUNAMBOL_APP_STORE
#import "MainView.h"
#import "SettingsView.h"
#else
#import "MainSingleView.h"
#import "SettingsSingleView.h"
#endif
#import "LogView.h"
#import "base/Log.h"
#import "customs.h"

using namespace Funambol;

static UIController*  uic_instance = nil;

@implementation UIController

- (id)init {

    self = [super init];

    return self;
}

- (void)dealloc {

    [super dealloc];
}

- (void)stopSyncContacts{
#ifdef FUNAMBOL_APP_STORE
        [mainSingleView cancelContactSyncArrowAnimation];
        [mainSingleView resetSyncIcons];
        [mainSingleView enableAllButtons];
#else   
        [mainView cancelSyncArrowAnimation:@"addressbook"];
        [mainView resetSyncIcons];
        [mainView enableAllButtons];
#endif
    [[FunambolAPI getInstance] stopSyncContacts];
}

- (void)sync:(NSString*) sourcename{
    syncAllFlag = false;

    if([sourcename isEqualToString:@"addressbook"]){
        contactsToSend    = -1;
        contactsToReceive = -1;
        contactsSent      = 0;
        contactsReceived  = 0;
#ifdef FUNAMBOL_APP_STORE
        [mainSingleView disableAllButtons];
        [mainSingleView updateContactSyncStatus:NSLocalizedString(@"(Connecting...)",@"(Connecting...)")];
        [mainSingleView startContactSyncArrowAnimation];
        
#else
        [mainView disableAllButtons];
        
        [mainView setSyncAllView];
        [mainView startSyncArrowAnimation:@"addressbook"];
        [mainView updateItemSyncStatus:NSLocalizedString(@"(Connecting...)",@"(Connecting...)") sourcename:@"addressbook"];

    }else if([sourcename isEqualToString:@"calendar"]){
        
        calendarToSend    = -1;
        calendarToReceive = -1;
        calendarSent      = 0;
        calendarReceived  = 0;
        [mainView disableAllButtons];
        [mainView setSyncAllView];
        [mainView updateItemSyncStatus:NSLocalizedString(@"(Connecting...)",@"(Connecting...)") sourcename:@"calendar"];
        [mainView startSyncArrowAnimation:@"calendar"];
    }else if([sourcename isEqualToString:@"note"]){
        
        notesToSend    = -1;
        notesToReceive = -1;
        notesSent      = 0;
        notesReceived  = 0;
        [mainView disableAllButtons];
        [mainView setSyncAllView];
        [mainView updateItemSyncStatus:NSLocalizedString(@"(Connecting...)",@"(Connecting...)") 
                               iconIdx:MAIN_VIEW_STATUS_ICON_NULL sourcename:@"note"];
        [mainView startSyncArrowAnimation:@"note"];
#endif
    }
    LOG.debug("Starting a new sync thread");
    if([sourcename isEqualToString:@"addressbook"]){
        [[FunambolAPI getInstance] syncContactsInThread:self];
    }else if([sourcename isEqualToString:@"calendar"]){
        [[FunambolAPI getInstance] syncCalendarInThread:self];
    }else if([sourcename isEqualToString:@"note"]){
        [[FunambolAPI getInstance] syncNotesInThread:self];
    }
}

- (void)recoverContacts {
    //[mainView removeViewLogButton];
#ifdef FUNAMBOL_APP_STORE
        [mainSingleView disableAllButtons];
        [mainSingleView updateContactSyncStatus:NSLocalizedString(@"(Connecting...)",@"(Connecting...)")];
        [mainSingleView startContactSyncArrowAnimation];
#else

        [mainView disableAllButtons];
        [mainView updateItemSyncStatus:NSLocalizedString(@"(Connecting...)",@"(Connecting...)") sourcename:@"addressbook"];
        [mainView startSyncArrowAnimation:@"addressbook"];

#endif
    LOG.debug("Starting a new sync thread");
    [[FunambolAPI getInstance] recoverContactsInThread:self];
}


- (void)cleanupContacts {
    //[mainView removeViewLogButton];
#ifdef FUNAMBOL_APP_STORE
        [mainSingleView disableAllButtons];
        [mainSingleView updateContactSyncStatus:NSLocalizedString(@"(Cleaning Up ...)",@"(Cleaning Up ...)")];
        [mainSingleView startContactSyncArrowAnimation];
#else        
        [mainView disableAllButtons];
        [mainView updateItemSyncStatus:NSLocalizedString(@"(Cleaning Up ...)",@"(Cleaning Up ...)") sourcename:@"addressbook"];
        [mainView startSyncArrowAnimation:@"addressbook"];
#endif
    LOG.debug("Starting a new sync thread");
    [[FunambolAPI getInstance] cleanupContactsInThread:self];
    
    
}
#ifndef FUNAMBOL_APP_STORE
- (void)cleanup: (bool)contactFlag calendarFlag: (bool) calendarFlag noteFlag: (bool) noteFlag {
    syncAllFlag = true;
    [mainView setSyncAllView];
    if(contactFlag){
        [mainView disableAllButtons];
        [mainView startSyncArrowAnimation:@"addressbook"];
        [mainView updateItemSyncStatus:NSLocalizedString(@"(Cleaning Up ...)",@"(Cleaning Up ...)") sourcename:@"addressbook"];
        
    }
    if(calendarFlag){
        
        [mainView disableAllButtons];
        [mainView updateItemSyncStatus:NSLocalizedString(@"(Cleaning Up ...)",@"(Cleaning Up ...)") sourcename:@"calendar"];
        [mainView startSyncArrowAnimation:@"calendar"];
    }
    if(noteFlag){
        [mainView disableAllButtons];
        [mainView updateItemSyncStatus:NSLocalizedString(@"(Cleaning Up ...)",@"(Cleaning Up ...)") sourcename:@"note"];
        [mainView startSyncArrowAnimation:@"note"];
    }

    // Sync all available sources
    [[FunambolAPI getInstance] cleanupInThread:self contactFlag:contactFlag calendarFlag:calendarFlag noteFlag:noteFlag];
}
#endif

- (void)syncAll {
    syncAllFlag = true;


#ifndef FUNAMBOL_APP_STORE
        [mainView setSyncAllView];
        if(![[[FunambolAPI getInstance]getSync:@"addressbook"] isEqualToString:@"none"]){
            contactsToSend    = -1;
            contactsToReceive = -1;
            contactsSent      = 0;
            contactsReceived  = 0;
            [mainView disableAllButtons];
            [mainView startSyncArrowAnimation:@"addressbook"];
            [mainView updateItemSyncStatus:NSLocalizedString(@"(Connecting...)",@"(Connecting...)") sourcename:@"addressbook"];
        }
        if(![[[FunambolAPI getInstance]getSync:@"calendar"] isEqualToString:@"none"]){
        
            calendarToSend    = -1;
            calendarToReceive = -1;
            calendarSent      = 0;
            calendarReceived  = 0;
            [mainView disableAllButtons];
            [mainView updateItemSyncStatus:NSLocalizedString(@"(Connecting...)",@"(Connecting...)") sourcename:@"calendar"];
            [mainView startSyncArrowAnimation:@"calendar"];
        }
        if(![[[FunambolAPI getInstance]getSync:@"note"] isEqualToString:@"none"]){

            notesToSend    = -1;
            notesToReceive = -1;
            notesSent      = 0;
            notesReceived  = 0;
            [mainView disableAllButtons];
            [mainView updateItemSyncStatus:NSLocalizedString(@"(Connecting...)",@"(Connecting...)") sourcename:@"note"];
            [mainView startSyncArrowAnimation:@"note"];
        }
#else

        [mainSingleView setSyncAllView];
        if(![[[FunambolAPI getInstance]getSync:@"addressbook"] isEqualToString:@"none"]){
            contactsToSend    = -1;
            contactsToReceive = -1;
            contactsSent      = 0;
            contactsReceived  = 0;
            [mainSingleView disableAllButtons];
            [mainSingleView startContactSyncArrowAnimation];
            [mainSingleView updateContactSyncStatus:NSLocalizedString(@"(Connecting...)",@"(Connecting...)") ];
        }
#endif
    // Sync all available sources
    [[FunambolAPI getInstance] syncAllInThread:self];
}

+ (UIController*)getInstance {
    if (uic_instance == nil) {
        uic_instance = [[UIController alloc] init];
    }
    return uic_instance;
}


- (void) updateUIOnItemReceived:(NSString*) sourcename {
    int itemsReceived;
    int itemsToReceive;
    if([sourcename isEqualToString:@"addressbook"]){
        ++contactsReceived;
        itemsReceived = contactsReceived;
        itemsToReceive = contactsToReceive;
    }else if([sourcename isEqualToString:@"calendar"]){
        ++calendarReceived;
        itemsReceived = calendarReceived;
        itemsToReceive = calendarToReceive;
    }else if([sourcename isEqualToString:@"note"]){
        ++notesReceived;
        itemsReceived = notesReceived;
        itemsToReceive = notesToReceive;
    }
    NSString *mmsg;
    if (itemsToReceive > 0) {
        mmsg = [NSString stringWithFormat:NSLocalizedString(@"Receiving (%d/%d)",@"Receiving (%d/%d)"),
                                  itemsReceived, itemsToReceive];
    } else {
        mmsg = [NSString stringWithFormat:NSLocalizedString(@"Receiving (%d)",@"Receiving (%d)"),
                                  itemsReceived];
    }
    //[mainView updateContactSyncStatus:msg];
#ifdef FUNAMBOL_APP_STORE
        [mainSingleView updateContactSyncStatusDuringSync:mmsg];
#else        
        [mainView updateItemsSyncStatusDuringSync:sourcename msg:mmsg];
#endif
}

- (void) sendFinishing: (NSString*)sourcename isReceiving:(bool) isReceiving{
#ifdef FUNAMBOL_APP_STORE
        if(isReceiving){
            [mainSingleView updateContactSyncStatus:NSLocalizedString(@"(Finishing...)",@"(Finishing...)")];  
        }else {
            [mainSingleView updateContactSyncStatus:NSLocalizedString(@"(Waiting...)",@"(Waiting...)")];
            
        }
#else
        if(isReceiving){
            [mainView updateItemsSyncStatusDuringSync:sourcename msg:NSLocalizedString(@"(Finishing...)",@"(Finishing...)")];    
        }else {
            [mainView updateItemsSyncStatusDuringSync:sourcename msg:NSLocalizedString(@"(Waiting...)",@"(Waiting...)")];
            
        }
#endif
}

- (void) updateUIOnItemSent: (NSString*) sourcename {
    int itemsSent;
    int itemsToSend;
    
    if([sourcename isEqualToString:@"addressbook"]){
        ++contactsSent;
        itemsSent = contactsSent;
        itemsToSend = contactsToSend;
    }else if([sourcename isEqualToString:@"calendar"]){
        ++calendarSent;
        itemsSent = calendarSent;
        itemsToSend = calendarToSend;
    }else if([sourcename isEqualToString:@"note"]){
        ++notesSent;
        itemsSent = notesSent;
        itemsToSend = notesToSend;
    }
    NSString *mmsg;
    
    if (itemsToSend > 0) {
        mmsg = [[NSString alloc] initWithFormat:NSLocalizedString(@"Sending (%d/%d)",@"Sending (%d/%d)"),
                                  itemsSent, itemsToSend];
    } else {
        mmsg = [[NSString alloc] initWithFormat:NSLocalizedString(@"Sending (%d)",@"Sending (%d)"),
                                  itemsSent];
    }
#ifdef FUNAMBOL_APP_STORE
        [mainSingleView updateContactSyncStatusDuringSync:mmsg];
#else
        [mainView updateItemsSyncStatusDuringSync:sourcename msg:mmsg];
#endif
    //[mainView updateContactSyncStatus:msg];
    //[msg release];
}



- (void) receivedAddItem: (NSString*) sourcename {
    LOG.debug("Received new %s", [sourcename UTF8String]);
    [self updateUIOnItemReceived: sourcename];
}

- (void) receivedDeleteItem: (NSString*) sourcename {
    LOG.debug("Received delete %s", [sourcename UTF8String]);
    [self updateUIOnItemReceived: sourcename];
}

- (void) receivedUpdateItem: (NSString*) sourcename  {
    LOG.debug("Received update %s", [sourcename UTF8String]);
    [self updateUIOnItemReceived: sourcename];
}

- (void) sentAddItem: (NSString*) sourcename  {
    LOG.debug("Sent new %s", [sourcename UTF8String]);
    [self updateUIOnItemSent: sourcename];
}

- (void) sentDeleteItem: (NSString*) sourcename  {
    LOG.debug("Sent delete %s", [sourcename UTF8String]);
    [self updateUIOnItemSent:sourcename];
}

- (void) sentUpdateItem: (NSString*) sourcename  {
    LOG.debug("Sent update %s", [sourcename UTF8String]);
    [self updateUIOnItemSent:sourcename];
}

- (void)beginSync:(NSString*) sourcename {
    if([sourcename isEqualToString:@"addressbook"]){
        contactsToSend    = -1;
        contactsToReceive = -1;
        contactsSent      = 0;
        contactsReceived  = 0;
#ifndef FUNAMBOL_APP_STORE
        [mainView setStartSyncAnimation:@"addressbook" start:true];
        [mainView setSyncSourceView:@"addressbook"];
#endif
        
    }
#ifndef FUNAMBOL_APP_STORE
    else if([sourcename isEqualToString:@"calendar"]){
        
        calendarToSend    = -1;
        calendarToReceive = -1;
        calendarSent      = 0;
        calendarReceived  = 0;
        [mainView setStartSyncAnimation:@"calendar" start:true];
        [mainView setSyncSourceView:@"calendar"];
        
    }else if([sourcename isEqualToString:@"note"]){
        
        notesToSend    = -1;
        notesToReceive = -1;
        notesSent      = 0;
        notesReceived  = 0;
        [mainView setStartSyncAnimation:@"note" start:true];
        [mainView setSyncSourceView:@"note"];

    }
#endif
}


- (void) endCleanUp{
#ifdef FUNAMBOL_APP_STORE
        [mainSingleView updateContactSyncStatus:NSLocalizedString(@"Clean Up successful", @"Clean Up successful")
                                  iconIdx:MAIN_SINGLE_VIEW_STATUS_ICON_SUCCESS];

#else
        [mainView updateItemSyncStatus:NSLocalizedString(@"Clean Up successful", @"Clean Up successful")
                              iconIdx:MAIN_VIEW_STATUS_ICON_SUCCESS  sourcename:@"addressbook"];
#endif
}

#ifndef FUNAMBOL_APP_STORE

- (void) endCleanup:(int)res sname:(NSString*) sname{
    
    [mainView updateItemSyncStatus:NSLocalizedString(@"Clean Up successful", @"Clean Up successful")
                       iconIdx:MAIN_VIEW_STATUS_ICON_SUCCESS  sourcename:sname];
    [mainView cancelSyncArrowAnimation:sname];
    // Reset icons set during sync
    [mainView removeButtonBlue:sname];

}
#endif

- (void)endSync:(int)res sourcename:(NSString*) sourcename {
    if([sourcename isEqualToString:@"addressbook"]){
#ifdef FUNAMBOL_APP_STORE
        
        // Cancel the main view arrows
        [mainSingleView cancelContactSyncArrowAnimation];
        // Report contacts status
        if (res == 0) {
            [mainSingleView updateContactSyncStatus:NSLocalizedString(@"Synchronization successful", @"Synchronization successful")
                                            iconIdx:MAIN_SINGLE_VIEW_STATUS_ICON_SUCCESS];
            
        } else {
            [mainSingleView updateContactSyncStatus:NSLocalizedString(@"Synchronization failure", @"Synchronization failure")
                                            iconIdx:MAIN_SINGLE_VIEW_STATUS_ICON_FAILURE];
            [mainSingleView showMessage:[self getErrorMessage:res]  titleText:NSLocalizedString(@"Alert", @"Alert")];
            
        }
        // Reset icons set during sync
        [mainSingleView resetSyncIcons];
        [mainSingleView enableAllButtons];
    }
#else        
    
    // Report contacts status
        if (res == 0) {
            //[mainView updateItemsSyncStatusDuringSync:@"addressbook" msg:NSLocalizedString(@"Synchronization successful", @"Synchronization successful")];
            [mainView updateItemSyncStatus:NSLocalizedString(@"Synchronization successful", @"Synchronization successful")
                               iconIdx:MAIN_VIEW_STATUS_ICON_SUCCESS  sourcename:@"addressbook"];
            [mainView setFinalMsg:@"addressbook" result:res];
        } else {
            [mainView updateItemSyncStatus:NSLocalizedString(@"Synchronization failure", @"Synchronization failure")
                               iconIdx:MAIN_VIEW_STATUS_ICON_FAILURE  sourcename:@"addressbook"];
            [mainView showMessage:[self getErrorMessage:res]  titleText:NSLocalizedString(@"Alert", @"Alert")];
        }
        // Cancel the main view arrows
        [mainView cancelSyncArrowAnimation:@"addressbook"];
        // Reset icons set during sync
        [mainView removeButtonBlue:@"addressbook"];
        if (!syncAllFlag){
            [mainView resetSyncIcons];
            [mainView enableAllButtons];
        }
    } else if([sourcename isEqualToString:@"calendar"]){
        [mainView cancelSyncArrowAnimation:@"calendar"];
        // Report contacts status
        if (res == 0) {
            [mainView updateItemSyncStatus:NSLocalizedString(@"Synchronization successful", @"Synchronization successful")
                                   iconIdx:MAIN_VIEW_STATUS_ICON_SUCCESS  sourcename:@"calendar"];
            
        } else {
            [mainView updateItemSyncStatus:NSLocalizedString(@"Synchronization failure", @"Synchronization failure")
                                   iconIdx:MAIN_VIEW_STATUS_ICON_FAILURE  sourcename:@"calendar"];
            [mainView showMessage:[self getErrorMessage:res]  titleText:NSLocalizedString(@"Alert", @"Alert")];
            
        }
        // Reset icons set during sync
        [mainView removeButtonBlue:@"calendar"];
        if(!syncAllFlag){
            [mainView resetSyncIcons];
            [mainView enableAllButtons];
        }
    }else if([sourcename isEqualToString:@"note"]){
        [mainView cancelSyncArrowAnimation:@"note"];
        // Report contacts status
        if (res == 0) {
            [mainView updateItemSyncStatus:NSLocalizedString(@"Synchronization successful", @"Synchronization successful")
                                   iconIdx:MAIN_VIEW_STATUS_ICON_SUCCESS  sourcename:@"note"];
            
        } else {
            [mainView updateItemSyncStatus:NSLocalizedString(@"Synchronization failure", @"Synchronization failure")
                                   iconIdx:MAIN_VIEW_STATUS_ICON_FAILURE  sourcename:@"note"];
            [mainView showMessage:[self getErrorMessage:res]  titleText:NSLocalizedString(@"Alert", @"Alert")];
            
        }
        // Reset icons set during sync
        [mainView removeButtonBlue:@"note"];
        if(!syncAllFlag){
            [mainView resetSyncIcons];
            [mainView enableAllButtons];
        }
    }
#endif
}

- (void) endSyncAll{

#ifndef FUNAMBOL_APP_STORE
        [mainView resetSyncIcons];
        [mainView enableAllButtons];
#else 
        [mainSingleView resetSyncIcons];
        [mainSingleView enableAllButtons];
#endif
}
- (void)sendingClientItems: (NSString*) sourcename num:(int)num {
    LOG.debug("Total %s items to send: %d",[sourcename UTF8String], num);
    if([sourcename isEqualToString:@"addressbook"]){
        contactsToSend = num;
    }else if([sourcename isEqualToString:@"calendar"]){
        calendarToSend = num;
    }else if([sourcename isEqualToString:@"note"]){
        notesToSend = num;
    }
}

- (void)receivingServerItems: (NSString*) sourcename num:(int)num {
    LOG.debug("Total %s items to receive: %d",[sourcename UTF8String], num);
    if([sourcename isEqualToString:@"addressbook"]){
        contactsToReceive = num;
    }else if([sourcename isEqualToString:@"calendar"]){
        calendarToReceive = num;
    }else if([sourcename isEqualToString:@"note"]){
        notesToReceive = num;
    }
}

- (void) loadSyncConfig:(NSString**) url
               username:(NSString**) username
               password:(NSString**) password {

    [[FunambolAPI getInstance] loadSyncConfig: url
                               username:username
                               password:password];
}

- (void) saveSettings:(NSString*)url
             username:(NSString*)username
             password:(NSString*)password {

    [[FunambolAPI getInstance] saveSyncConfig: url
                                     username:username
                                     password:password];
}

- (void)saveURL:(NSString*) url{
    [[FunambolAPI getInstance] saveURLConfig:url];
}

- (void)saveUsername:(NSString*) username{
    [[FunambolAPI getInstance] saveUsernameConfig:username];
}
- (void)savePassword:(NSString*) password{
    [[FunambolAPI getInstance] savePasswordConfig:password];
}

- (void) setMainSingleView: (MainSingleView*)val{

        mainSingleView = val;
}
#ifndef FUNAMBOL_APP_STORE
- (void) setMainView: (MainView*)val{
        mainView = val;

}
#endif

- (NSString*) getErrorMessage: (int) errorValue{
    switch (errorValue) {
        case 401:
            return NSLocalizedString(@"Error401", @"Error401");
            break;
        case 402:
            return NSLocalizedString(@"Error402", @"Error402");
            break;
        case 404:
            return NSLocalizedString(@"Error404", @"Error404");
            break;
        case 407:
            return NSLocalizedString(@"Error407", @"Error407");
            break;
        case 417:
            return NSLocalizedString(@"Error417", @"Error417");
            break;
        case 503:
            return NSLocalizedString(@"Error503", @"Error503");
            break;
        case 2001:
            return NSLocalizedString(@"Error2001", @"Error2001");
            break;
        case 2002:
            return NSLocalizedString(@"Error2002", @"Error2002");
            break;
        case 2003:
            return NSLocalizedString(@"Error2003", @"Error2003");
            break;
        case 2005:
            return NSLocalizedString(@"Error2005", @"Error2005");
            break;
        case 2007:
            return NSLocalizedString(@"Error2007", @"Error2007");
            break;
        case 2052:
            return NSLocalizedString(@"Error2052", @"Error2052");
            break;
        case 2053:
            return NSLocalizedString(@"Error2053", @"Error2053");
            break;
        case 2060:
            return NSLocalizedString(@"Error2060", @"Error2060");
            break;
        case 2061:
            return NSLocalizedString(@"Error2061", @"Error2061");
            break;
        default:
            return NSLocalizedString(@"ErrorGeneric",@"Generic error");;
            break;
    }
}


@end
